package Presetacion;

import Negocio.Estado;
import Negocio.MetodoBusqueda;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Tablero.java
 *
 * Created on 08-oct-2011, 18:27:06
 */
/**
 *
 * @author Rodrigo
 */
public class Tablero extends javax.swing.JPanel {

    /** Creates new form Tablero */
    ArrayList<Casillero> casilleros = new ArrayList<Casillero>();
    ArrayList<Ficha> fichas = new ArrayList<Ficha>();
    private String imagen = null;
    private int columna = 0, fila = 0;
    private Estado estFinal;
    private boolean iniciado=false;

    public Tablero() {
        initComponents();
    }

    public void iniciar(int row, int col, String img) {
        imagen = img;
        columna = col;
        fila = row;
        this.setOpaque(false);
        setLayout(new java.awt.GridLayout(row, col));

        casilleros.clear();
        casilleros.ensureCapacity(col * row);

        try {
            for (BufferedImage im : splitImage(ImageIO.read(new File(img)), col, row)) {
                casilleros.add(new Casillero(casilleros.size(), this, new Ficha(casilleros.size(), new ImageIcon(im), false)));
            }
        } catch (Exception ex) {
            casilleros.clear();
            for (int i = 0; i < (row * col); i++) {
                casilleros.add(new Casillero(i, this, new Ficha(i, "" + i, false)));
            }
        }

        casilleros.get(casilleros.size() - 1).setFicha(new Ficha(casilleros.size() - 1, "", true));


        this.removeAll();
        fichas.clear();
        for (final Casillero cas : casilleros) {
            int f = (cas.getPosicion() / this.fila);
            int c = cas.getPosicion() - f * this.columna;

            try {
                cas.addVecino(this.getCasillero(f, c - 1));
            } catch (Exception ex) {
            }
            try {
                cas.addVecino(this.getCasillero(f, c + 1));
            } catch (Exception ex) {
            }
            try {
                cas.addVecino(this.getCasillero(f + 1, c));
            } catch (Exception ex) {
            }
            try {
                cas.addVecino(this.getCasillero(f - 1, c));
            } catch (Exception ex) {
            }
            this.add(cas);
            fichas.add(cas.getFicha());
        }


        estFinal = getEstado();
        Estado.setVacio((row * col) - 1);

        this.revalidate();
        this.repaint();
        iniciado=true;

    }

    public void validar() {
        for (final Casillero cas : casilleros) {
            if (cas.getPosicion() != cas.getFicha().getId()) {
                return;
            }
        }

        JOptionPane.showMessageDialog(this, "LO LOGRASTE!!!!", "FELICIDADES", JOptionPane.INFORMATION_MESSAGE);
    }

    public Estado getEstadoFinal() {
        return estFinal;
    }

    public void desordenar(int cant) {
        Casillero cas1, cas2;
        for (int i = 0; i < cant; i++) {
            cas1 = fichas.get(fichas.size() - 1).getCasillero();
            cas2 = cas1.getVecionos().get(getRandom(0, cas1.getVecionos().size()));

            Ficha ficha = cas1.getFicha();
            cas1.setFicha(cas2.getFicha());
            cas2.setFicha(ficha);

        }
        this.repaint();
    }

    public int getRandom(int min, int max) {
        return (int) (min + Math.floor(Math.random() * (max - min)));
    }

    public static BufferedImage[] splitImage(BufferedImage img, int cols, int rows) {
        int w = img.getWidth() / cols;
        int h = img.getHeight() / rows;
        int num = 0;
        BufferedImage imgs[] = new BufferedImage[cols * rows];
        for (int y = 0; y < rows; y++) {
            for (int x = 0; x < cols; x++) {
                imgs[num] = new BufferedImage(w, h, img.getType());
                // Tell the graphics to draw only one block of the image  
                Graphics2D g = imgs[num].createGraphics();
                g.drawImage(img, 0, 0, w, h, w * x, h * y, w * x + w, h * y + h, null);
                g.dispose();
                num++;
            }
        }
        return imgs;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setLayout(null);
    }// </editor-fold>//GEN-END:initComponents

    public Estado getEstado() {
        int[][] estado = new int[fila][columna];
        for (int fila = 0; fila < this.fila; fila++) {
            for (int colum = 0; colum < this.columna; colum++) {
                estado[fila][colum] = getID(fila, colum);
            }
        }

        int fila = -1;
        int columna = -1;
        for (int i = 0; i < estado.length; i++) {
            for (int j = 0; j < estado[0].length; j++) {
                if (estado[i][j] == Estado.getVacio()) {
                    fila = i;
                    columna = j;
                }
            }
        }
        Estado temp = new Estado(estado);
        temp.setFila_vacio(fila);
        temp.setColumna_vacio(columna);
        return temp;
    }

    private int getID(int row, int col) {
        if (casilleros.size() <= (col + col * row) || (col + col * row) < 0) {
            throw new RuntimeException("Le herraste al indice");
        }
        return casilleros.get(col + this.columna * row).getFicha().getId();
    }

    private void setID(int row, int col, int id) {
        if (casilleros.size() <= (col + col * row) || (col + col * row) < 0) {
            throw new RuntimeException("Le herraste al indice");
        }
        casilleros.get(col + this.columna * row).setFicha(fichas.get(id));
    }

    private Casillero getCasillero(int row, int col) {
        if ((0 <= col && col < this.columna) == false) {
            throw new RuntimeException("Le herraste al indice");
        }

        if ((0 <= row && row < this.columna) == false) {
            throw new RuntimeException("Le herraste al indice");
        }

        return casilleros.get(col + this.columna * row);
    }

    public void setEstado(Estado est) {
        if(est==null)        
        {
            for(Casillero cas:casilleros)
                cas.setFicha(new Ficha(cas.getPosicion(), "", true)); 
            return;
        }
        
        int[][] estado = est.getMatriz();
        for (int fila = 0; fila < this.fila; fila++) {
            for (int colum = 0; colum < this.columna; colum++) {
                setID(fila, colum, estado[fila][colum]);
            }
        }
        this.repaint();
    }
    
    public int getColumnas() {
        return columna;
    }

    public int getFilas() {
        return fila;
    }

    public String getImagenURL() {
        return imagen;
    }    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    public boolean isIniciado() {
       return iniciado;
    }

 
}
